package cn.zou.mvc;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javassist.NotFoundException;

public class BaseServlect extends HttpServlet{
	private Map<String,Method> map;
	@Override
	public void init() throws ServletException {
		super.init();
		RequestUtils requestUtils=new RequestUtils();
		map=requestUtils.getMethd(this.getClass());
	}

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//super.service(request, response);
		response.setContentType("text/html;charset=UTF-8");//处理响应编码
		request.setCharacterEncoding("UTF-8");
		//获取访问路径
		String path= request.getRequestURI().toString();
		//获取访问方法
		Method method= map.get(path);
		if(method==null){ 
			error(response,"请求方法路径错误，或不存在");}
		else{
			//执行方法 并获取到返回值
			//执行方法前先进行参数的注入
			Class<?>[] parameterTypes = method.getParameterTypes();
			try {
				//获取到参数名
				String[] pramasName = new PramasNameUtils().getPramasName(this.getClass(), parameterTypes);
				//对参数进行依赖注入
				Object[] oprams= injection(request,parameterTypes,pramasName,response);
				//执行对应方法
				String result = (String)method.invoke(this, oprams).toString();
				if(result != null && !result.trim().isEmpty()) {//如果请求处理方法返回不为空
					int index = result.indexOf(":");//获取第一个冒号的位置
					if(index == -1) {//如果没有冒号，使用转发
						request.getRequestDispatcher(result).forward(request, response);
					} else {//如果存在冒号
						String start = result.substring(0, index);//分割出前缀
						String returnpath = result.substring(index + 1);//分割出路径
						if(start.equals("f")) {//前缀为f表示转发
							request.getRequestDispatcher(returnpath).forward(request, response);
						} else if(start.equals("r")) {//前缀为r表示重定向
							response.sendRedirect(request.getContextPath() + returnpath);
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				//error(response,"处理数据注入时出错");
			}
		}
	}
	/**
	 * 将请求的参数进行对于方法的依赖注入
	 * @param request 请求
	 * @param parameterTypes 方法参数类型
	 * @param pramasName 方法的参数名
	 * @return
	 * @throws ParseException 
	 * @throws InstantiationException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws ClassNotFoundException 
	 * @throws NumberFormatException 
	 */
	private Object[] injection(HttpServletRequest request, Class<?>[] parameterTypes, String[] pramasName,HttpServletResponse response) throws NumberFormatException, ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, ParseException {
		
		return new InjectionUtils().injection(request, parameterTypes, pramasName, response);
	}

	private void error(HttpServletResponse response,String s) {
		// TODO Auto-generated method stub
		PrintWriter writer =null;
		try {
			response.setContentType("text/plain;charset=UTF-8");
			writer = response.getWriter();
			writer.write(s);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			writer.close();
		}
	}
	
}
